package com.maomi.coder;

import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.*;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.Term;
import org.apache.lucene.queryparser.classic.ParseException;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.*;
import org.apache.lucene.store.Directory;

import java.io.IOException;

/**
 * 各种 query
 * Created by lucky on 2019-03-28.
 */
public class QueryDemo {

    private static String[] ids = new String[]{"1","2","3","4"};

    private static Double[] prices = new Double[]{10.0,100.0,70.0,80.0};

    private static String[] goodsName = new String[]{"钱包","书包","巧克力","裤子"};

    private static String[] englishName = new String[]{"wallet","schoolbag","chocolate","pants"};

    public static void writeIndex(IndexWriter writer) throws IOException {
        FieldType fieldType = new FieldType();
        //是否被分词
        fieldType.setTokenized(true);
        //是否存储
        fieldType.setStored(true);
        for (int i = 0 ; i < ids.length ; i ++){
            Document document = new Document();
            //使用field 创建
            document.add(new Field("id",ids[i],fieldType));
            //使用数字field创建
            document.add(new DoubleDocValuesField("price",prices[i]));
            //使用String field创建
            document.add(new StringField("goods",goodsName[i], Field.Store.YES));
            //使用Text field创建
            document.add(new TextField("name",englishName[i], Field.Store.YES));
            //添加文档
            writer.addDocument(document);
        }
        writer.commit();
    }

    public static void queryParse(String path,LuceneDemo luceneDemo) throws IOException, ParseException {
        Directory directory = luceneDemo.getDirectory(path);
        //打开读索引
        DirectoryReader reader = DirectoryReader.open(directory);

        IndexSearcher is = new IndexSearcher(reader);
        //lucene 查询解析器
        QueryParser parser = new QueryParser("id", new StandardAnalyzer());

        Query query = parser.parse("*:*");

        System.out.println("query:"+query);

        Sort sort = new Sort();
        //排序 默认 升序
        SortField sortField = new SortField("price",SortField.Type.DOUBLE);
        sort.setSort(sortField);

        TopDocs topDocs = is.search(query,100,sort);

        print(topDocs,is);

        //关闭读索引
        reader.close();
    }

    public static void print(TopDocs topDocs, IndexSearcher is) throws IOException {
        System.out.println("查询评分:"+topDocs.getMaxScore());

        for (ScoreDoc scoreDoc:topDocs.scoreDocs) {
            Document doc = is.doc(scoreDoc.doc);
            System.out.println(doc.get("id") + "-" + doc.get("goods") + "-" + doc.get("name"));
        }
    }

    public static void termQuery(String path,LuceneDemo luceneDemo)  throws IOException, ParseException {
        Directory directory = luceneDemo.getDirectory(path);
        //打开读索引
        DirectoryReader reader = DirectoryReader.open(directory);

        IndexSearcher is = new IndexSearcher(reader);

        TermQuery query = new TermQuery(new Term("name", "wallet"));

        System.out.println("query:"+query);

        TopDocs topDocs = is.search(query,100);

        print(topDocs,is);

        reader.close();
    }

    public static void termRangeQuery(String path,LuceneDemo luceneDemo) throws IOException, ParseException{
        Directory directory = luceneDemo.getDirectory(path);
        //打开读索引
        DirectoryReader reader = DirectoryReader.open(directory);

        IndexSearcher is = new IndexSearcher(reader);

        TermRangeQuery query = TermRangeQuery.newStringRange("name", "a", "z", true, false);
        TopDocs topDocs = is.search(query,100);

        print(topDocs,is);

        reader.close();
    }

    public static void booleanQuery(String path,LuceneDemo luceneDemo) throws IOException, ParseException{
        Directory directory = luceneDemo.getDirectory(path);
        //打开读索引
        DirectoryReader reader = DirectoryReader.open(directory);

        IndexSearcher is = new IndexSearcher(reader);

        BooleanQuery.Builder builder = new BooleanQuery.Builder();


        TermRangeQuery query = TermRangeQuery.newStringRange("name", "p", "z", true, true);

        QueryParser parser = new QueryParser("name", new StandardAnalyzer());

        Query parse = parser.parse("+schoolbag -pants");

        builder.add(query, BooleanClause.Occur.MUST);
        builder.add(parse, BooleanClause.Occur.MUST);

        BooleanQuery build = builder.build();

        TopDocs topDocs = is.search(build,100);

        print(topDocs,is);

        reader.close();
    }

    public static void main(String[] args) throws IOException, ParseException {
        String path = System.getProperty("java.io.tmpdir") + "queryIndex";
        System.out.println(path);
        LuceneDemo luceneDemo = new LuceneDemo();

        IndexWriter writer = luceneDemo.getWriter(path);
        //创建索引
        writeIndex(writer);
        writer.close();

        //解析查询
//        queryParse(path,luceneDemo);

        //项查询
//        termQuery(path,luceneDemo);

        //项指定范围查询
//        termRangeQuery(path,luceneDemo);

        //BOOLEAN 查询
//        booleanQuery(path,luceneDemo);
    }
}
